using System;
using Firestarter.Test.Base;
using FireStarterModeller.BO;
using FireStarterModeller.BO.BusinessObjectRules;
using Habanero.Base;
using Habanero.BO;
using NUnit.Framework;

namespace FireStarterModeller.Test.BO
{
    /// <summary>
    /// Provides a place to write custom tests for DMClass objects.
    /// This file is only written once and can be changed.  The Def file
    /// attached to this as a dependent is rewritten with each regeneration
    /// and contains the standard tests for DMClass.
    /// Regenerate this test project whenever there have been changes to the
    /// business objects.
    /// If tests are failing due to a unique setup in your application,
    /// you can either override the Create methods in TestUtils, or you
    /// can add the test to the ignore list below and reimplement it here.
    /// </summary>
    [TestFixture]
    public class TestDMClassAllSubClassesDiscriminatorsAreEqual
    {
        #region Setup/Teardown

        [SetUp]
        public void SetupTest()
        {
            //Runs every time that any testmethod is executed
            TestUtilsDomain.SetupTest();
            BORegistry.DataAccessor = new DataAccessorInMemory();
        }

        [TearDown]
        public void TearDownTest()
        {
            //runs every time any testmethod is complete
        }

        #endregion

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once.
            TestUtilsDomain.SetupFixture();
        }

       
        [Test]
        public void Test_CreateDMClassAllSubClassesDiscriminatorsAreEqualRule()
        {
            //---------------Set up test pack-------------------
            DMClass superClass = CreateSuperClassAndTwoSubClassesWithTheSameDiscriminators();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            IBusinessObjectRule rule = new DMClassAllSubClassesDiscriminatorsAreEqual();
            //---------------Test Result -----------------------
            Assert.IsNotNull(rule);
            Assert.AreEqual("AllSubClassesDiscriminatorsAreEqual", rule.Name);
            Assert.AreEqual(ErrorLevel.Error, rule.ErrorLevel);
        }


//        [Test]
//        public void Test_CreateDMClassAllSubClassesDiscriminatorsAreEqualRule_WhenClassNull_ShouldRaiseError()
//        {
//            //---------------Set up test pack-------------------
//            //---------------Assert Precondition----------------
//            //---------------Execute Test ----------------------
//            try
//            {
//                new DMClassAllSubClassesDiscriminatorsAreEqual(null);
//                Assert.Fail("expected ArgumentNullException");
//            }
//                //---------------Test Result -----------------------
//            catch (ArgumentNullException ex)
//            {
//                StringAssert.Contains("Value cannot be null", ex.Message);
//                StringAssert.Contains("dmClass", ex.ParamName);
//            }
//        }

        [Test]
        public void Test_DMClass_SubClassesHaveDifferentDiscriminators()
        {
            //---------------Set up test pack-------------------
            DMClass superClass = CreateSuperClassAndTwoSubClassesWithOneDifferentDiscriminators();
            DMClass subClass = superClass.SubClassRelationships[1].SubClass;
            IBusinessObjectRule rule = new DMClassAllSubClassesDiscriminatorsAreEqual();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(superClass);
            //---------------Test Result -----------------------
            Assert.AreEqual(superClass, ((DMClassAllSubClassesDiscriminatorsAreEqual)rule).SuperClass);
            Assert.IsFalse(isValid);
            Assert.AreEqual(subClass, ((DMClassAllSubClassesDiscriminatorsAreEqual)rule).SubClass);
            StringAssert.Contains("The SubClass '" + subClass.ClassNameBO + "'s", rule.Message);
            StringAssert.Contains("discriminator is not ", rule.Message);
            StringAssert.Contains("the same as the other SubClasses of the Entity/Class '" + superClass + "'.", rule.Message);
        }

        [Test]
        public void Test_DMClass_WhenOneSubClassHasNoDiscriminator_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMClass superClass = CreateSuperClassAndTwoSubClassesOneWithNoDiscriminator();
            IBusinessObjectRule rule = new DMClassAllSubClassesDiscriminatorsAreEqual();
            //---------------Assert Precondition----------------
            
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(superClass);
            //---------------Test Result -----------------------
            Assert.AreEqual(superClass, ((DMClassAllSubClassesDiscriminatorsAreEqual)rule).SuperClass);
            Assert.IsTrue(isValid);
        }

        

        [Test]
        public void Test_DMClass_SubClassesHaveSameDiscriminators()
        {
            //---------------Set up test pack-------------------
            DMClass superClass = CreateSuperClassAndTwoSubClassesWithTheSameDiscriminators();
            IBusinessObjectRule rule = new DMClassAllSubClassesDiscriminatorsAreEqual();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(superClass);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

       
        private DMClass CreateSuperClassAndTwoSubClassesWithTheSameDiscriminators()
        {
            DMClass superClass = TestUtilsDMClass.CreateUnsavedDefaultDMClass("TestSuperClass");
            DMClass subClass1 = TestUtilsDMClass.CreateUnsavedDefaultDMClass("TestSubClass1");
            DMClass subClass2 = TestUtilsDMClass.CreateUnsavedDefaultDMClass("TestSubClass2");

            DMProperty discriminatorProp = TestUtilsDMProperty.SetDMPropStringType(new DMProperty());
            superClass.Properties.Add(discriminatorProp);

            superClass.SubClassRelationships.Add(GetDmInheritanceRelationship(superClass, subClass1,
                                                                              discriminatorProp.PropertyName));

            superClass.SubClassRelationships.Add(GetDmInheritanceRelationship(superClass, subClass2,
                                                                              discriminatorProp.PropertyName));
            return superClass;
        }



        private DMClass CreateSuperClassAndTwoSubClassesWithOneDifferentDiscriminators()
        {
            DMClass superClass = TestUtilsDMClass.CreateUnsavedDefaultDMClass("TestSuperClass");
            DMClass subClass1 = TestUtilsDMClass.CreateUnsavedDefaultDMClass("TestSubClass1");
            DMClass subClass2 = TestUtilsDMClass.CreateUnsavedDefaultDMClass("TestSubClass2");
            DMProperty discriminatorProp = TestUtilsDMProperty.SetDMPropStringType(new DMProperty());
            superClass.Properties.Add(discriminatorProp);
            superClass.SubClassRelationships.Add(GetDmInheritanceRelationship(superClass, subClass1,
                                                                               discriminatorProp.PropertyName));

            superClass.SubClassRelationships.Add(GetDmInheritanceRelationship(superClass, subClass2,
                                                                              "TestProp"));
            return superClass;
        }

        private DMClass CreateSuperClassAndTwoSubClassesOneWithNoDiscriminator()
        {
            DMClass superClass = TestUtilsDMClass.CreateUnsavedDefaultDMClass("TestSuperClass");
            DMClass subClass1 = TestUtilsDMClass.CreateUnsavedDefaultDMClass("TestSubClass1");
            DMClass subClass2 = TestUtilsDMClass.CreateUnsavedDefaultDMClass("TestSubClass2");
            DMProperty discriminatorProp = TestUtilsDMProperty.SetDMPropStringType(new DMProperty());
            superClass.Properties.Add(discriminatorProp);
            superClass.SubClassRelationships.Add(GetDmInheritanceRelationship(superClass, subClass1,
                                                                               ""));

            superClass.SubClassRelationships.Add(GetDmInheritanceRelationship(superClass, subClass2,
                                                                              "TestProp"));
            return superClass;
        }
        private DMInheritanceRelationship GetDmInheritanceRelationship(DMClass superClass, DMClass subClass1,
                                                                       string discriminatorProp)
        {
            DMInheritanceRelationship dmInheritanceRelationship1 = new DMInheritanceRelationship();
            dmInheritanceRelationship1.Discriminator = discriminatorProp;
            dmInheritanceRelationship1.SubClass = subClass1;
            dmInheritanceRelationship1.SuperClass = superClass;
            return dmInheritanceRelationship1;
        }

    }

    
}